package com.hevs.samplewebapp.server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;

import com.google.appengine.api.datastore.Key;
import com.hevs.samplewebapp.server.entities.MedicalRecord;
import com.hevs.samplewebapp.server.entities.User;
import com.hevs.samplewebapp.server.json.ObjectMapperFactory;
import com.hevs.samplewebapp.server.service.MedicalRecordService;
import com.hevs.samplewebapp.server.service.UserService;
import com.hevs.samplewebapp.server.util.CredentialValidator;

/**
 * 
 * @author Arnaud Durand creation : 12.03.12
 * 
 *         Goal: RESTful service used by doctors for patient's Medical Records
 *         management.
 * 
 */

public class MedicalRecordSupervisorServlet extends SessionAuthHttpServlet {

	private static final long serialVersionUID = 870866277965499216L;

	public static MedicalRecordService medicalRecordService;
	{
		medicalRecordService = new MedicalRecordService();
	};
	
	public static UserService userService;
	{
		userService = new UserService();
	};

	public MedicalRecordSupervisorServlet() {
		super(2);

		setGenericCustomValidation(new CredentialValidator() {

			@Override
			public boolean hasAccess(HttpServletRequest req,
					int requiredCredentialLevel) {
				System.out.println(req.getPathTranslated());

				System.out.println("--checking security--");

				HttpSession session = req.getSession(false);
				Key localUserKey;
				User remote;
				try {
					localUserKey = (Key) session.getAttribute("userKey");
					String userMail = req.getPathInfo().replace("/", "");
					System.out.println(req.getPathTranslated()
							+ "getPathTrans()");
					remote = userService.getUserByMail(userMail);
					if (remote == null) {
						System.out.println("remote==nul");
						return false;
					}

				} catch (Exception e) {
					System.out.println("catch exception");
					return false;
				}
				for (Key remoteUserKey : remote.getGrantedUsers()) {
					if (localUserKey.equals(remoteUserKey))
						return true;
				}
				System.out.println("key not found");
				return false;
			}
		});
		/*
		 * new CredentialValidation() {
		 * 
		 * @Override public boolean hasAccess(HttpServletRequest req, int
		 * requiredCredentialLevel) {
		 * System.out.println(req.getPathTranslated());
		 * 
		 * 
		 * User local = getAuthenticatedUser();
		 * 
		 * userDAO.getGrantedUsers(local) User remote =
		 * userDAO.getUserByMail(req.getPathTranslated());
		 * 
		 * if(userDAO.getUserByMail(req.getPathTranslated())) String. return
		 * false; } });
		 */
	}

	// update
	@Override
	protected void doSecurePut(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {

		// ObjectMapper mapper = new ObjectMapper(); // can reuse, share
		// globall
		BufferedReader reader = req.getReader();
		StringBuilder sb = new StringBuilder();
		String line = reader.readLine();
		while (line != null) {
			sb.append(line + "\n");
			line = reader.readLine();
		}
		reader.close();
		System.out.println(sb.toString());

		ObjectMapper mapper = ObjectMapperFactory.get();
		MedicalRecord medicalRecord = mapper.readValue(sb.toString(),
				MedicalRecord.class);

		// throw Error 400
		if (medicalRecord == null) {
			resp.sendError(400);
			return;
		}

		/*
		 * if (medicalRecord.getUser() != getAuthenticatedUser().getKey()) { //
		 * not authorized resp.sendError(403); return; }
		 */

		// medicalData.setUser(getAuthenticatedUser().getKey());
		medicalRecord.setUser(userService.getUserByMail(
				req.getPathInfo().replace("/", "")).getKey());
		medicalRecordService.updateMedicalRecord(medicalRecord);

	}

	// create
	@Override
	protected void doSecurePost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {

		// ObjectMapper mapper = new ObjectMapper(); // can reuse, share
		// globall
		BufferedReader reader = req.getReader();
		StringBuilder sb = new StringBuilder();
		String line = reader.readLine();
		while (line != null) {
			sb.append(line + "\n");
			line = reader.readLine();
		}
		reader.close();
		System.out.println(sb.toString());

		ObjectMapper mapper = ObjectMapperFactory.get();
		List<MedicalRecord> medicalRecords = mapper.readValue(sb.toString(),
				new TypeReference<ArrayList<MedicalRecord>>() {
				});

		for (MedicalRecord medicalRecord : medicalRecords) {
			medicalRecord.setUser(userService.getUserByMail(
					req.getPathInfo().replace("/", "")).getKey());
		}

		medicalRecordService.addMedicalRecords(medicalRecords);
	}

	@Override
	protected void doSecureDelete(HttpServletRequest req,
			HttpServletResponse resp) throws ServletException, IOException {

		try {

			// ObjectMapper mapper = new ObjectMapper(); // can reuse, share
			// globall
			BufferedReader reader = req.getReader();
			StringBuilder sb = new StringBuilder();
			String line = reader.readLine();
			while (line != null) {
				sb.append(line + "\n");
				line = reader.readLine();
			}
			reader.close();
			System.out.println(sb.toString());

			ObjectMapper mapper = ObjectMapperFactory.get();
			MedicalRecord medicalRecord = mapper.readValue(sb.toString(),
					MedicalRecord.class);

			if (medicalRecord == null || medicalRecord.getKey() == null) {
				// bad request
				resp.sendError(400);
				return;
			}

			medicalRecordService.removeMedicalRecord(medicalRecord);

		} catch (Exception e) {
			e.printStackTrace();
			throw new ServletException(e);
		}
	}

	@Override
	protected void doSecureGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {

	
		System.out.println(req.getPathInfo());
		System.out.println(req.getPathInfo().replace("/", ""));
		User user = userService.getUserByMail(req.getPathInfo().replace("/", ""));

		List<MedicalRecord> medicalRecords;
		try {

			medicalRecords = medicalRecordService.getAllMedicalRecords(user);

			ObjectMapper mapper = ObjectMapperFactory.get();

			resp.setContentType("application/json");
			PrintWriter writer = resp.getWriter();
			writer.write(mapper.writeValueAsString(medicalRecords));

			writer.flush();

		} catch (Exception e) {
			e.printStackTrace();
			throw new ServletException(e);
		}

	}

}
